package com.tsq.weixin.provider.controller;

import com.tsq.common.model.ResponseData;
import com.tsq.weixin.api.form.WxH5OuthrizeForm;
import com.tsq.weixin.api.model.WxUser;
import com.tsq.weixin.api.utils.*;
import com.tsq.weixin.provider.service.WxUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpOAuth2AccessToken;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;

@RestController
@RequestMapping("/wxAuth")
@RequiredArgsConstructor
@Api(value = "WxAuthController", tags = {"微信网页授权相关"})
public class WxAuthController {
    Logger logger = LoggerFactory.getLogger(this.getClass());
    private final WxMpService wxMpService;

    @Autowired
    private WxUserService wxUserService;


    @PostMapping("/codeToOpenid")
    @CrossOrigin
    @ApiOperation(value = "使用微信授权code换取openid", notes = "使用微信授权code换取openid")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "request", dataType = "HttpServletRequest", paramType = "head"),
            @ApiImplicitParam(name = "response", value = "response", dataType = "HttpServletResponse", paramType = "head"),
            @ApiImplicitParam(name = "appid", value = "appid", dataType = "String", paramType = "head"),
            @ApiImplicitParam(name = "form", value = "code属性", dataType = "WxH5OuthrizeForm", paramType = "body")
    })
    public ResponseData<String> codeToOpenid(HttpServletRequest request,
                                             HttpServletResponse response,
                                             @RequestHeader String appid,
                                             @RequestBody WxH5OuthrizeForm form) {

        try {
            this.wxMpService.switchoverTo(appid);
            WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(form.getCode());
            String openid = token.getOpenId();
            CookieUtil.setCookie(response, "openid", openid, 365 * 24 * 60 * 60);
            String openidToken = MD5Util.getMD5AndSalt(openid);
            CookieUtil.setCookie(response, "openidToken", openidToken, 365 * 24 * 60 * 60);
            return ResponseData.success(openid);
        } catch (WxErrorException e) {
            logger.error("code换取openid失败", e);
            return ResponseData.error(e.getError().getErrorMsg());
        }
    }

    @PostMapping("/codeToUserInfo")
    @CrossOrigin
    @ApiOperation(value = "使用微信授权code换取用户信息(需scope为 snsapi_userinfo)", notes = "使用微信授权code换取用户信息(需scope为 snsapi_userinfo)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "request", dataType = "HttpServletRequest", paramType = "head"),
            @ApiImplicitParam(name = "response", value = "response", dataType = "HttpServletResponse", paramType = "head"),
            @ApiImplicitParam(name = "appid", value = "appid", dataType = "String", paramType = "head"),
            @ApiImplicitParam(name = "form", value = "WxH5OuthrizeForm对象", dataType = "WxH5OuthrizeForm", paramType = "body")
    })
    public ResponseData<WxUser> codeToUserInfo(HttpServletRequest request,
                                               HttpServletResponse response,
                                               @RequestHeader String appid,
                                               @RequestBody WxH5OuthrizeForm form) {

        try {
            this.wxMpService.switchoverTo(appid);
            WxMpOAuth2AccessToken token = wxMpService.oauth2getAccessToken(form.getCode());
            WxMpUser userInfo = wxMpService.oauth2getUserInfo(token,"zh_CN");
            String openid = userInfo.getOpenId();
            CookieUtil.setCookie(response, "openid", openid, 365 * 24 * 60 * 60);
            String openidToken = MD5Util.getMD5AndSalt(openid);
            CookieUtil.setCookie(response, "openidToken", openidToken, 365 * 24 * 60 * 60);
            return ResponseData.success(wxUserService.getById(openid));
        } catch (WxErrorException e) {
            logger.error("code换取用户信息失败", e);
            return ResponseData.error(e.getError().getErrorMsg());
        }
    }

    @GetMapping("/getShareSignature")
    @ApiOperation(value = "获取微信分享的签名配置", notes = "获取微信分享的签名配置")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "request", value = "request", dataType = "HttpServletRequest", paramType = "head"),
            @ApiImplicitParam(name = "response", value = "response", dataType = "HttpServletResponse", paramType = "head"),
            @ApiImplicitParam(name = "appid", value = "appid", dataType = "String", paramType = "head")
    })
    public ResponseData<Map<String, String>> getShareSignature(HttpServletRequest request,
                                                               HttpServletResponse response,
                                                               @RequestHeader String appid) throws WxErrorException {

        this.wxMpService.switchoverTo(appid);
        // 1.拼接url（当前网页的URL，不包含#及其后面部分）
        String wxShareUrl = request.getHeader(Constant.WX_CLIENT_HREF_HEADER);
        if (StringUtils.isEmpty(wxShareUrl)) {
            return ResponseData.error("header中缺少"+Constant.WX_CLIENT_HREF_HEADER+"参数，微信分享加载失败");
        }
        wxShareUrl = wxShareUrl.split("#")[0];
        Map<String, String> wxMap = new TreeMap<>();
        String wxNoncestr = UUID.randomUUID().toString();
        String wxTimestamp = (System.currentTimeMillis() / 1000) + "";
        wxMap.put("noncestr", wxNoncestr);
        wxMap.put("timestamp", wxTimestamp);
        wxMap.put("jsapi_ticket", wxMpService.getJsapiTicket());
        wxMap.put("url", wxShareUrl);

        // 加密获取signature
        StringBuilder wxBaseString = new StringBuilder();
        wxMap.forEach((key, value) -> wxBaseString.append(key).append("=").append(value).append("&"));
        String wxSignString = wxBaseString.substring(0, wxBaseString.length() - 1);
        // signature
        String wxSignature = SHA1Util.sha1(wxSignString);
        Map<String, String> resMap = new TreeMap<>();
        resMap.put("appId", appid);
        resMap.put("wxTimestamp", wxTimestamp);
        resMap.put("wxNoncestr", wxNoncestr);
        resMap.put("wxSignature", wxSignature);
        return ResponseData.success(resMap);
    }

    @GetMapping("/getCode")
    @ApiOperation(value = "获取code详情回调方法", notes = "获取code详情回调方法")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "code", value = "code", dataType = "String", paramType = "param")
    })
    public ResponseData<String> getUserInfo(@RequestParam String code){
        return ResponseData.success(code);
    }

}
